home *** CD-ROM | disk | FTP | other *** search
- /* NOS User Session control
- * Copyright 1991 Phil Karn, KA9Q
- *
- * Mods by PA0GRI
- */
- #include "global.h"
- #include "commands.h"
- #include "mbuf.h"
- #include "proc.h"
- #include "ftpcli.h"
- #include "icmp.h"
- #ifndef UNIX
- #include "main.h"
- #endif
-
- #if !defined(_lint)
- static char rcsid[] OPTIONAL = "$Id: session.c,v 1.23 1997/08/19 01:19:22 root Exp root $";
- #endif
-
- struct session *Sessions;
- struct session *Command;
- struct session *Current;
- struct session *Lastcurr;
- #ifndef UNIX
- extern unsigned char SCREENlength;
- #endif
- #ifdef UNIX
- extern int Numrows;
- #endif
-
- extern int INStatline, BLOCKStatline;
- #if defined(UNIX)
- extern void statLineToggle (int clearmarquee);
- #endif
- static void upload (int unused,void *sp1,void *p);
-
- char Notval[] = "Not a valid control block\n";
- static char Badsess[] = "Invalid session\n";
- char TooManySessions[] = "Too many sessions\n";
-
- const char *Sestypes[] =
- {
- "", /* The command session */
- "Telnet",
- "FTP",
- "AX25",
- "Finger",
- "Ping",
- "NET/ROM",
- "Command",
- "More",
- "Hopcheck",
- "Tip",
- "PPP PAP",
- "Dial",
- "Query",
- "Cache",
- "Rlogin",
- #ifdef UNIX
- "Trace",
- #else
- "", /* The trace session */
- #endif
- "View",
- "Script",
- "Repeat",
- "Resolve",
- "DNSquery",
- "Look",
- "AXUI"
- };
-
-
-
- /* Convert a character string containing a decimal session index number
- * into a pointer. If the arg is NULLCHAR, use the current default session.
- * If the index is out of range or unused, return NULLSESSION.
- */
- struct session *
- sessptr (char *cp)
- {
- register struct session *sp;
- unsigned int i;
-
- if (cp == NULLCHAR)
- sp = Lastcurr;
- else {
- i = (unsigned) atoi (cp);
- if (i >= Nsessions)
- sp = NULLSESSION;
- else
- sp = &Sessions[i];
- }
- if (sp == NULLSESSION || sp->type == FREE)
- sp = NULLSESSION;
-
- return sp;
- }
-
-
-
- /* Select and display sessions */
- int
- dosession (int argc, char *argv[], void *p)
- {
- struct session *sp;
- struct sockaddr fsocket;
- int i, k = 0, s;
- int r, t;
- char const *cp;
- char *param[3];
-
- sp = (struct session *) p;
-
- if (argc > 1) {
- if ((sp = sessptr (argv[1])) == NULLSESSION) {
- tprintf ("Session %s not active\n", argv[1]);
- return 1;
- }
- if (argc == 2)
- (void) go (0, NULL, sp);
-
- param[0] = argv[2];
- param[1] = argv[3];
- param[2] = NULL;
- if (argc > 2) {
- switch (*argv[2]) {
- case 'f': /* flowmode */
- (void) setbool (&sp->flowmode, "Set flowmode on/off", argc - 2, param);
- break;
- default:
- tputs ("usage:session # [flow [on/off]]\n");
- }
- }
- return 0;
- }
- tputs (" # S# Type Rcv-Q Snd-Q State Remote socket\n");
- for (sp = Sessions; sp < &Sessions[Nsessions]; sp++) {
- if (sp->type == FREE || sp->type == COMMAND || sp->type == TRACESESSION)
- continue;
-
- /* Rcv-Q includes output pending at the screen driver */
- r = socklen (sp->output, 1);
- t = 0;
- cp = NULLCHAR;
- if ((s = sp->s) != -1) {
- i = SOCKSIZE;
- s = sp->s;
- k = getpeername (s, (char *) &fsocket, &i);
- r += socklen (s, 0);
- t += socklen (s, 1);
- cp = sockstate (s);
- }
- tprintf ("%c", (Lastcurr == sp) ? '*' : ' ');
- tprintf ("%-3u", (unsigned) (sp - Sessions));
- tprintf ("%-4d%-8s%6d%6d %-13s", s, Sestypes[sp->type], r, t,
- (cp != NULLCHAR) ? cp : "Limbo!");
- if (sp->name != NULLCHAR)
- tprintf ("%s ", sp->name);
- if (sp->s != -1 && k == 0)
- tprintf ("(%s)", psocket (&fsocket));
-
- tputc ('\n');
- if (sp->type == FTP && (s = sp->cb.ftp->data) != -1) {
- /* Display data channel, if any */
- i = SOCKSIZE;
- k = getpeername (s, (char *) &fsocket, &i);
- r = socklen (s, 0);
- t = socklen (s, 1);
- cp = sockstate (s);
- tprintf (" %-4d%-8s%6d%6d %-13s%s", s, Sestypes[sp->type],
- r, t, (cp != NULLCHAR) ? cp : "Limbo!",
- (sp->name != NULLCHAR) ? sp->name : "");
- if (k == 0)
- tprintf (" (%s)", psocket (&fsocket));
- if (tputc ('\n') == EOF)
- break;
- }
- if (sp->rfile != NULLCHAR)
- tprintf (" Record: %s\n", sp->rfile);
- if (sp->ufile != NULLCHAR)
- tprintf (" Upload: %s\n", sp->ufile);
- }
- return 0;
- }
-
-
-
- /* Resume current session, and wait for it */
- int
- go (int argc OPTIONAL, char *argv[] OPTIONAL, void *p)
- {
- struct session *sp;
-
- sp = (struct session *) p;
- if (sp == NULLSESSION || sp->type == FREE || sp->type == COMMAND || sp->type == TRACESESSION)
- return 0;
- Current = sp;
- swapscreen (Command, sp);
- ksignal (sp, 0);
- return 0;
- }
-
-
-
- int
- doclose (int argc, char *argv[], void *p)
- {
- struct session *sp;
-
- sp = (struct session *) p;
- if (argc > 1)
- sp = sessptr (argv[1]);
-
- if (sp == NULLSESSION) {
- tputs (Badsess);
- return -1;
- }
- (void) shutdown (sp->s, 1);
- return 0;
- }
-
-
-
- int
- doreset (int argc, char *argv[], void *p)
- {
- struct session *sp;
-
- sp = (struct session *) p;
- if (argc > 1)
- sp = sessptr (argv[1]);
-
- if (sp == NULLSESSION) {
- tputs (Badsess);
- return -1;
- }
- /* Unwedge anyone waiting for a domain resolution, etc */
- alert (sp->proc, EABORT);
- (void) shutdown (sp->s, 2);
- if (sp->type == FTP)
- (void) shutdown (sp->cb.ftp->data, 2);
- return 0;
- }
-
-
-
- int
- dokick (int argc, char *argv[], void *p)
- {
- struct session *sp;
-
- sp = (struct session *) p;
- if (argc > 1)
- sp = sessptr (argv[1]);
-
- if (sp == NULLSESSION) {
- tputs (Badsess);
- return -1;
- }
- (void) sockkick (sp->s);
- if (sp->type == FTP)
- (void) sockkick (sp->cb.ftp->data);
- return 0;
- }
-
-
- #ifdef UNIX
- extern int STATLINE;
- #endif
-
-
-
- struct session *
- newsession (const char *name, int type, int split)
- {
- register struct session *sp;
- int i;
-
- /* Reserve the highest session for Trace, so that
- * the F-key session switching works correctly - WG7J
- */
- if (type == TRACESESSION) { /* This can only get called once !! */
- i = 0;
- sp = Sessions;
- while ((unsigned) i != Nsessions - 1) {
- i++;
- sp++;
- }
- } else {
- for (i = 0, sp = Sessions; (unsigned) i < Nsessions; sp++, i++)
- if (sp->type == FREE)
- break;
- }
- if ((unsigned) i == Nsessions)
- return NULLSESSION;
-
- sp->type = type;
- sp->s = -1;
- if (name != NULLCHAR)
- sp->name = strdup (name);
- else
- sp->name = NULLCHAR;
- sp->proc = Curproc;
- #ifdef UNIX
- /* update Curproc's session pointer as well! */
- /* (in theory this could leave a dangling session...?) */
- Curproc->session = sp;
- #endif
- /* Create standard input and output sockets. Output is
- * translated to local end-of-line by default
- */
- Curproc->input = sp->input = socket (AF_LOCAL, SOCK_STREAM, 0);
- (void) seteol (Curproc->input, Eol);
- (void) sockmode (Curproc->input, SOCK_BINARY);
- Curproc->output = sp->output = socket (AF_LOCAL, SOCK_STREAM, 0);
- (void) seteol (Curproc->output, Eol);
- (void) sockmode (Curproc->output, SOCK_ASCII);
-
- /* on by default */
- sp->ttystate.crnl = sp->ttystate.edit = sp->ttystate.echo = 1;
- sp->flowmode = 0; /* Off by default */
- #ifdef UNIX
- sp->row = Numrows - 1 - (split * 2);
- #else
- sp->row = SCREENlength - 1 - (split * 2);
- #endif
- sp->morewait = 0;
- sp->split = split;
- newscreen (sp);
- swapscreen (Current, sp);
- Current = sp;
- #ifdef UNIX
- sp->screen->statline = uchar (STATLINE);
- if (STATLINE) {
- statLineToggle (0);
- statLineToggle (0);
- }
- #endif
- return sp;
- }
-
-
-
- void
- freesession (struct session *sp)
- {
- if (sp == NULLSESSION)
- return;
- kwait (NULL); /* Wait for any pending output to go */
- rflush ();
-
- if (sp->proc1 != NULLPROC)
- killproc (sp->proc1);
- sp->proc1 = NULLPROC;
- if (sp->proc2 != NULLPROC)
- killproc (sp->proc2);
- sp->proc2 = NULLPROC;
-
- free_p (sp->ttystate.line);
- sp->ttystate.line = NULLBUF;
- if (sp->s != -1)
- close_s (sp->s);
- if (sp->record != NULLFILE) {
- (void) fclose (sp->record);
- sp->record = NULLFILE;
- }
- free (sp->rfile);
- sp->rfile = NULLCHAR;
- if (sp->upload != NULLFILE) {
- (void) fclose (sp->upload);
- sp->upload = NULLFILE;
- }
- free (sp->ufile);
- sp->ufile = NULLCHAR;
- free (sp->name);
- sp->name = NULLCHAR;
- sp->type = FREE;
-
- close_s (sp->input);
- sp->input = -1;
- sp->proc->input = -1;
- close_s (sp->output);
- sp->output = -1;
- sp->proc->output = -1;
-
- sp->screen->statline = 0;
-
- while (INStatline)
- kwait (NULL);
- BLOCKStatline += 1;
-
- freescreen (sp);
- if (Current == sp) {
- Current = Command;
- swapscreen (NULLSESSION, Command);
- #ifndef UNIX
- alert (Display, 1);
- #endif
- }
- #ifdef UNIX
- /* reparent process to command session */
- sp->proc->session = Command;
- #endif
- BLOCKStatline -= 1;
- if (Lastcurr == sp)
- Lastcurr = NULLSESSION;
- }
-
-
-
- #ifdef ALLCMD
- /* Control session recording */
- int
- dorecord (int argc, char *argv[], void *p)
- {
- struct session *sp;
- char const *mode;
- char fname[128];
-
- sp = (struct session *) p;
- if (sp == NULLSESSION) {
- tputs ("No current session\n");
- return 1;
- }
- if (argc > 1) {
- if (sp->rfile != NULLCHAR) {
- (void) fclose (sp->record);
- free (sp->rfile);
- sp->record = NULLFILE;
- sp->rfile = NULLCHAR;
- }
- /* Open new record file, unless file name is "off", which means
- * disable recording
- */
- if (strcmp (argv[1], "off") != 0) {
- if (sockmode (sp->output, -1) == SOCK_ASCII)
- mode = APPEND_TEXT;
- else
- mode = APPEND_BINARY;
-
- strncpy (fname, make_fname (Command->curdirs->dir, argv[1]), 128);
- if ((sp->record = fopen (fname, mode)) == NULLFILE)
- tprintf ("Can't open %s: %s\n", fname, SYS_ERRLIST(errno));
- else
- sp->rfile = strdup (fname);
- }
- }
- if (sp->rfile != NULLCHAR)
- tprintf ("Recording into %s\n", sp->rfile);
- else
- tputs ("Recording off\n");
- return 0;
- }
-
-
-
- /* Control file transmission */
- int
- doupload (int argc, char *argv[], void *p)
- {
- register struct session *sp;
- char fname[128];
-
- sp = (struct session *) p;
- if (sp == NULLSESSION) {
- tputs ("No current session\n");
- return 1;
- }
- if (argc < 2) {
- if (sp->ufile != NULLCHAR)
- tprintf ("Uploading %s\n", sp->ufile);
- else
- tputs ("Uploading off\n");
- return 0;
- }
- if (strcmp (argv[1], "stop") == 0 && sp->upload != NULLFILE) {
- /* Abort upload */
- (void) fclose (sp->upload);
- sp->upload = NULLFILE;
- free (sp->ufile);
- sp->ufile = NULLCHAR;
- killproc (sp->proc2);
- sp->proc2 = NULLPROC;
- return 0;
- }
- /* Open upload file */
- strncpy (fname, make_fname (Command->curdirs->dir, argv[1]), 128);
- if ((sp->upload = fopen (fname, READ_TEXT)) == NULLFILE) {
- tprintf ("Can't read %s: %s\n", fname, SYS_ERRLIST(errno));
- return 1;
- }
- sp->ufile = strdup (fname);
- /* All set, invoke the upload process */
- sp->proc2 = newproc ("upload", 1024, upload, 0, sp, NULL, 0);
- return 0;
- }
-
-
-
- /* File uploading task */
- static void
- upload (int unused OPTIONAL, void *sp1, void *p OPTIONAL)
- {
- struct session *sp;
- int oldf;
- char *buf;
-
- sp = (struct session *) sp1;
-
- /* Disable newline buffering for the duration */
- oldf = setflush (sp->s, -1);
-
- buf = mallocw (BUFSIZ);
- while (fgets (buf, BUFSIZ, sp->upload) != NULLCHAR)
- if (usputs (sp->s, buf) == EOF)
- break;
-
- free (buf);
- usflush (sp->s);
- (void) setflush (sp->s, oldf);
- (void) fclose (sp->upload);
- sp->upload = NULLFILE;
- free (sp->ufile);
- sp->ufile = NULLCHAR;
- sp->proc2 = NULLPROC;
- }
- #endif /*ALLCMD*/
-
-
-
- /* Flush the current session's standard output. Called on every clock tick */
- void
- sesflush(void)
- {
- if (Current != NULL)
- usflush (Current->output);
- }
-
-
-